home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / VBSamples / Demos / AirHockey / cInput.cls < prev    next >
Encoding:
Visual Basic class definition  |  2001-10-08  |  14.0 KB  |  398 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "cInput"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15.  
  16. 'Here we will control all of the input, from any source
  17. 'List of camera views (same enum listed in the camera class)
  18. Private Enum DefaultCameraViews
  19.     DefaultView
  20.     OverHeadView
  21.     SideOverheadView1
  22.     SideOverheadView2
  23.     OpponentView
  24.     CustomView
  25. End Enum
  26.  
  27. '*NOTE*
  28. '
  29. 'I may want to add Force Feedback support, if i do, I would do so here.
  30.  
  31. 'Mouse constants
  32. Private Const mlJoystickRange As Long = 35
  33. Private Const mnMaxZThresh As Single = 35
  34. Private Const mnMaxYThresh As Single = 50
  35. Private Const mnMaxXThresh As Single = 35
  36.  
  37. 'DirectInput variables, etc
  38. Private Const glBufferSize As Long = 10
  39. 'DInput objects
  40. Private di As DirectInput8
  41. Private diMouse As DirectInputDevice8
  42. Private diKeyboard As DirectInputDevice8
  43. Private diJoystick As DirectInputDevice8
  44. 'Is the camera moving?
  45. Private mfMovingCamera As Boolean
  46.  
  47. 'Local properties to determine what controls should be used
  48. Public UseMouse As Boolean
  49. Public UseKeyboard As Boolean
  50. Public UseJoystick As Boolean
  51. Public JoystickGuid As String
  52. Public JoystickSensitivity As Single
  53. Public MouseSensitivity As Single
  54. Public KeyboardSensitivity As Single
  55.  
  56. Public Property Get InputObject() As DirectInput8
  57.     Set InputObject = di
  58. End Property
  59.  
  60. Public Function InitDirectInput(oForm As Form) As Boolean
  61.   
  62.     Dim diProp As DIPROPLONG
  63.     Dim diProp_Dead As DIPROPLONG
  64.     Dim diProp_Range As DIPROPRANGE
  65.     Dim diProp_Saturation As DIPROPLONG
  66.     
  67.     On Error GoTo FailedInput
  68.     
  69.     InitDirectInput = True
  70.     'Create the DirectInput object, and all of the devices we need.
  71.     If UseMouse Then
  72.         Set diMouse = di.CreateDevice("guid_SysMouse")
  73.         diMouse.SetCommonDataFormat DIFORMAT_MOUSE
  74.         diMouse.SetCooperativeLevel oForm.hwnd, DISCL_FOREGROUND Or DISCL_EXCLUSIVE
  75.     
  76.         ' Set the buffer size
  77.         diProp.lHow = DIPH_DEVICE
  78.         diProp.lObj = 0
  79.         diProp.lData = glBufferSize
  80.         Call diMouse.SetProperty("DIPROP_BUFFERSIZE", diProp)
  81.         'Acquire the mouse
  82.         diMouse.Acquire
  83.     End If
  84.     
  85.     If UseKeyboard Then
  86.         Set diKeyboard = di.CreateDevice("GUID_SysKeyboard")
  87.         
  88.         diKeyboard.SetCommonDataFormat DIFORMAT_KEYBOARD
  89.         diKeyboard.SetCooperativeLevel oForm.hwnd, DISCL_FOREGROUND Or DISCL_NONEXCLUSIVE
  90.         'Acquire the keyboard
  91.         diKeyboard.Acquire
  92.     End If
  93.     
  94.     If UseJoystick Then
  95.         On Error Resume Next
  96.         Set diJoystick = di.CreateDevice(JoystickGuid)
  97.         If Err Then 'This joystick doesn't exist anymore
  98.             UseJoystick = False
  99.             Exit Function
  100.         End If
  101.         On Error GoTo FailedInput
  102.         diJoystick.SetCommonDataFormat DIFORMAT_JOYSTICK
  103.         diJoystick.SetCooperativeLevel oForm.hwnd, DISCL_FOREGROUND Or DISCL_EXCLUSIVE
  104.         
  105.         'Set deadzone to 10 percent
  106.         With diProp_Dead
  107.             .lData = mlJoystickRange \ 20
  108.             .lHow = DIPH_BYOFFSET
  109.             .lObj = DIJOFS_X
  110.             diJoystick.SetProperty "DIPROP_DEADZONE", diProp_Dead
  111.             .lObj = DIJOFS_Y
  112.             diJoystick.SetProperty "DIPROP_DEADZONE", diProp_Dead
  113.         End With
  114.         
  115.         'Set saturation zones to 5 percent
  116.         With diProp_Saturation
  117.             .lData = mlJoystickRange \ 40
  118.             .lHow = DIPH_BYOFFSET
  119.             .lObj = DIJOFS_X
  120.              diJoystick.SetProperty "DIPROP_SATURATION", diProp_Saturation
  121.             .lObj = DIJOFS_Y
  122.              diJoystick.SetProperty "DIPROP_SATURATION", diProp_Saturation
  123.         End With
  124.     
  125.         'Just in case this device doesn't let us set the range
  126.         On Error Resume Next
  127.         'Set range for all axes
  128.         With diProp_Range
  129.             .lHow = DIPH_DEVICE
  130.             .lMin = -mlJoystickRange
  131.             .lMax = mlJoystickRange
  132.         End With
  133.         diJoystick.SetProperty "DIPROP_RANGE", diProp_Range
  134.         On Error GoTo FailedInput
  135.         
  136.         diJoystick.Acquire
  137.     End If
  138.     
  139.     Exit Function
  140.   
  141. FailedInput:
  142.     InitDirectInput = False
  143.  
  144. End Function
  145.  
  146. Private Sub ProcessMouseData(oPaddle As cPaddle, oPuck As cPuck)
  147.     'This is where we respond to any change in mouse state. Usually this will be an axis movement
  148.     'or button press or release
  149.  
  150.     Dim diDeviceData(1 To glBufferSize) As DIDEVICEOBJECTDATA
  151.     Dim lNumItems As Long
  152.     Dim lCount As Integer
  153.     Dim lTempX As Single, lTempZ As Single
  154.   
  155.     On Error GoTo INPUTLOST 'In case we lost the mouse
  156.     diMouse.Acquire 'Just in case
  157.     lNumItems = diMouse.GetDeviceData(diDeviceData, 0)
  158.     On Error GoTo 0 'Reset our error
  159.     
  160.     ' Process data
  161.     For lCount = 1 To lNumItems
  162.         Select Case diDeviceData(lCount).lOfs
  163.         Case DIMOFS_X 'We moved the X axis
  164.             If mfMovingCamera Then
  165.                 With goCamera.Position
  166.                     If lTempZ = 0 Then lTempZ = .z
  167.                     lTempX = .X + (diDeviceData(lCount).lData * MouseSensitivity)
  168.                     goCamera.SetCameraPosition CustomView, oPaddle.PaddleID
  169.                     If Abs(lTempX) > mnMaxXThresh Then
  170.                         'Whoops too much
  171.                         lTempX = mnMaxXThresh * (lTempX / Abs(lTempX))
  172.                     End If
  173.                 End With
  174.             Else
  175.                 With oPaddle.Position
  176.                     If lTempZ = 0 Then lTempZ = .z
  177.                     lTempX = .X + (diDeviceData(lCount).lData * MouseSensitivity)
  178.                 End With
  179.             End If
  180.         Case DIMOFS_Y 'We moved the Y axis
  181.             If mfMovingCamera Then
  182.                 With goCamera.Position
  183.                     If lTempX = 0 Then lTempX = .X
  184.                     lTempZ = .z - (diDeviceData(lCount).lData * MouseSensitivity)
  185.                     goCamera.SetCameraPosition CustomView, oPaddle.PaddleID
  186.                     If Abs(lTempZ) > mnMaxZThresh Then
  187.                         'Whoops too much
  188.                         lTempZ = mnMaxZThresh * (lTempZ / Abs(lTempZ))
  189.                     End If
  190.                 End With
  191.             Else
  192.                 With oPaddle.Position
  193.                     If lTempX = 0 Then lTempX = .X
  194.                     lTempZ = .z - (diDeviceData(lCount).lData * MouseSensitivity)
  195.                 End With
  196.             End If
  197.         Case DIMOFS_BUTTON1
  198.             mfMovingCamera = (diDeviceData(lCount).lData And &H80 = &H80)
  199.         End Select
  200.     Next lCount
  201.     'Ok, this sequence is done, process the info, and move on
  202.     If lTempX <> 0 And lTempZ <> 0 Then
  203.         If mfMovingCamera Then
  204.             goCamera.Position = vec3(lTempX, goCamera.Position.Y, lTempZ)
  205.         Else
  206.             oPaddle.LastPosition = oPaddle.Position
  207.             oPaddle.Position = vec3(lTempX, oPaddle.Position.Y, lTempZ)
  208.             oPaddle.Velocity = vec3(oPaddle.Position.X - oPaddle.LastPosition.X, oPaddle.Velocity.Y, oPaddle.Position.z - oPaddle.LastPosition.z)
  209.             oPaddle.LastVelocityTick = timeGetTime
  210.         End If
  211.     End If
  212.     MakeSurePaddleIsOnBoard oPaddle
  213.     Exit Sub
  214.     
  215. INPUTLOST:
  216.     If (Err.Number = DIERR_INPUTLOST) Or (Err.Number = DIERR_NOTACQUIRED) Then
  217.         'We no longer have the mouse..
  218.     End If
  219. End Sub
  220.  
  221. Private Sub ProcessKeyBoardData(oPaddle As cPaddle, oPuck As cPuck)
  222.     
  223.     'This is where we respond to any change in keyboard state. Usually this will be an axis movement
  224.     'or button press or release
  225.     
  226.     Dim diKeys As DIKEYBOARDSTATE
  227.     Dim lTempX As Single, lTempZ As Single
  228.     
  229.     On Error GoTo INPUTLOST 'In case we lost focus
  230.     diKeyboard.Acquire 'Just in case
  231.     diKeyboard.GetDeviceStateKeyboard diKeys
  232.     
  233.     If KeyPressed(diKeys, DIK_LEFTARROW) Or KeyPressed(diKeys, DIK_NUMPAD4) Then
  234.         oPaddle.LastPosition = oPaddle.Position
  235.         With oPaddle.Position
  236.             lTempX = .X - KeyboardSensitivity
  237.             oPaddle.Position = vec3(lTempX, .Y, .z)
  238.         End With
  239.         oPaddle.Velocity = vec3(oPaddle.Position.X - oPaddle.LastPosition.X, oPaddle.Velocity.Y, oPaddle.Velocity.z)
  240.         oPaddle.LastVelocityTick = timeGetTime
  241.     End If
  242.     If KeyPressed(diKeys, DIK_RIGHTARROW) Or KeyPressed(diKeys, DIK_NUMPAD6) Then
  243.         oPaddle.LastPosition = oPaddle.Position
  244.         With oPaddle.Position
  245.             lTempX = .X + KeyboardSensitivity
  246.             oPaddle.Position = vec3(lTempX, .Y, .z)
  247.         End With
  248.         oPaddle.Velocity = vec3(oPaddle.Position.X - oPaddle.LastPosition.X, oPaddle.Velocity.Y, oPaddle.Velocity.z)
  249.         oPaddle.LastVelocityTick = timeGetTime
  250.     End If
  251.     If KeyPressed(diKeys, DIK_UPARROW) Or KeyPressed(diKeys, DIK_NUMPAD8) Then
  252.         oPaddle.LastPosition = oPaddle.Position
  253.         With oPaddle.Position
  254.             lTempZ = .z + KeyboardSensitivity
  255.             oPaddle.Position = vec3(.X, .Y, lTempZ)
  256.         End With
  257.         oPaddle.Velocity = vec3(oPaddle.Velocity.X, oPaddle.Velocity.Y, oPaddle.Position.z - oPaddle.LastPosition.z)
  258.         oPaddle.LastVelocityTick = timeGetTime
  259.     End If
  260.     If KeyPressed(diKeys, DIK_DOWNARROW) Or KeyPressed(diKeys, DIK_NUMPAD2) Then
  261.         oPaddle.LastPosition = oPaddle.Position
  262.         With oPaddle.Position
  263.             lTempZ = .z - KeyboardSensitivity
  264.             oPaddle.Position = vec3(.X, .Y, lTempZ)
  265.         End With
  266.         oPaddle.Velocity = vec3(oPaddle.Velocity.X, oPaddle.Velocity.Y, oPaddle.Position.z - oPaddle.LastPosition.z)
  267.         oPaddle.LastVelocityTick = timeGetTime
  268.     End If
  269.     
  270.     MakeSurePaddleIsOnBoard oPaddle
  271.     Exit Sub
  272.     
  273. INPUTLOST:
  274.     If (Err.Number = DIERR_INPUTLOST) Or (Err.Number = DIERR_NOTACQUIRED) Then
  275.         'We no longer have the mouse..
  276.     End If
  277. End Sub
  278.  
  279. Private Sub ProcessJoystickData(oPaddle As cPaddle, oPuck As cPuck)
  280.     
  281.     'This is where we respond to any change in keyboard state. Usually this will be an axis movement
  282.     'or button press or release
  283.     
  284.     Dim diJoy As DIJOYSTATE
  285.     Dim lTempX As Single, lTempZ As Single
  286.     
  287.     On Error GoTo INPUTLOST 'In case we lost focus
  288.     diJoystick.Acquire 'Just in case
  289.     diJoystick.Poll
  290.     diJoystick.GetDeviceStateJoystick diJoy
  291.     
  292.     If diJoy.X <> 0 Then
  293.         oPaddle.LastPosition = oPaddle.Position
  294.         With oPaddle.Position
  295.             lTempX = .X + (diJoy.X * JoystickSensitivity)
  296.             oPaddle.Position = vec3(lTempX, .Y, .z)
  297.         End With
  298.         oPaddle.Velocity = vec3(oPaddle.Position.X - oPaddle.LastPosition.X, oPaddle.Velocity.Y, oPaddle.Velocity.z)
  299.         oPaddle.LastVelocityTick = timeGetTime
  300.     End If
  301.     If diJoy.Y <> 0 Then
  302.         oPaddle.LastPosition = oPaddle.Position
  303.         With oPaddle.Position
  304.             lTempZ = .z - (diJoy.Y * JoystickSensitivity)
  305.             oPaddle.Position = vec3(.X, .Y, lTempZ)
  306.         End With
  307.         oPaddle.Velocity = vec3(oPaddle.Velocity.X, oPaddle.Velocity.Y, oPaddle.Position.z - oPaddle.LastPosition.z)
  308.         oPaddle.LastVelocityTick = timeGetTime
  309.     End If
  310.     
  311.     MakeSurePaddleIsOnBoard oPaddle
  312.     Exit Sub
  313.     
  314. INPUTLOST:
  315.     If (Err.Number = DIERR_INPUTLOST) Or (Err.Number = DIERR_NOTACQUIRED) Then
  316.         'We no longer have the joystick..
  317.     End If
  318. End Sub
  319.  
  320. Public Sub GetAndHandleInput(oPaddle As cPaddle, oPuck As cPuck)
  321.  
  322.     Dim vOldPaddle As D3DVECTOR
  323.     
  324.     oPaddle.Velocity = vec3(0, 0, 0)
  325.     vOldPaddle = oPaddle.Position
  326.     If UseMouse Then
  327.         'First let's handle the mouse
  328.         ProcessMouseData oPaddle, oPuck
  329.     End If
  330.         
  331.     If UseKeyboard Then
  332.         'Now we can worry about keyboard
  333.         ProcessKeyBoardData oPaddle, oPuck
  334.     End If
  335.     
  336.     If UseJoystick Then
  337.         'If we have a joystick selected check that too
  338.         ProcessJoystickData oPaddle, oPuck
  339.     End If
  340.     oPaddle.EnsureReality vOldPaddle, oPuck
  341. End Sub
  342.  
  343. 'Helper function to determine if a key is pressed
  344. Private Function KeyPressed(diKeys As DIKEYBOARDSTATE, Key As Byte)
  345.     KeyPressed = (diKeys.Key(Key) And &H80 = &H80)
  346. End Function
  347.  
  348. Private Function MakeSurePaddleIsOnBoard(oPaddle As cPaddle)
  349.     Dim lTempZ As Single, lTempX As Single
  350.     lTempX = oPaddle.Position.X
  351.     lTempZ = oPaddle.Position.z
  352.     
  353.     'Don't let the paddle leave the left or right sides of the table
  354.     If lTempX > (gnSideLeftWallEdge - (gnPaddleRadius)) Then
  355.         lTempX = (gnSideLeftWallEdge - (gnPaddleRadius))
  356.     ElseIf lTempX < (gnSideRightWallEdge + (gnPaddleRadius)) Then
  357.         lTempX = (gnSideRightWallEdge + (gnPaddleRadius))
  358.     End If
  359.     'Depending on which end of the table we are *supposed* to be on,
  360.     'restrict our movement.
  361.     If oPaddle.PaddleID = 0 Then
  362.         If lTempZ > -(gnPaddleRadius * 1.5) Then
  363.             lTempZ = -(gnPaddleRadius * 1.5)
  364.         ElseIf lTempZ < (gnFarWallEdge + (gnPaddleRadius)) Then
  365.             lTempZ = (gnFarWallEdge + (gnPaddleRadius))
  366.         End If
  367.     Else
  368.         If lTempZ > (gnNearWallEdge - (gnPaddleRadius)) Then
  369.             lTempZ = (gnNearWallEdge - (gnPaddleRadius))
  370.         ElseIf lTempZ < (gnPaddleRadius * 1.5) Then
  371.             lTempZ = (gnPaddleRadius * 1.5)
  372.         End If
  373.     End If
  374.     
  375.     oPaddle.Position = vec3(lTempX, oPaddle.Position.Y, lTempZ)
  376. End Function
  377.  
  378. Private Sub Class_Initialize()
  379.     Set diMouse = Nothing
  380.     Set diKeyboard = Nothing
  381.     Set diJoystick = Nothing
  382.     Set di = Nothing
  383.     Set di = dx.DirectInputCreate
  384. End Sub
  385.  
  386. Private Sub Class_Terminate()
  387.     On Error Resume Next 'Ignore any errors, we're cleaning everything up
  388.     'Unacquire the mouse
  389.     If Not (diMouse Is Nothing) Then diMouse.Unacquire
  390.     If Not (diKeyboard Is Nothing) Then diKeyboard.Unacquire
  391.     If Not (diJoystick Is Nothing) Then diJoystick.Unacquire
  392.     'Destroy our objects
  393.     Set diMouse = Nothing
  394.     Set diKeyboard = Nothing
  395.     Set diJoystick = Nothing
  396.     Set di = Nothing
  397. End Sub
  398.